gui = {
    window = {
        button = {
            new = function(self, name)
                local obj = {
                    win = self,
                    name = name,
                    text = nil,
                    position = {x = self.position.x or 0, y =  self.position.y or 0 },
                    padding = { left = 5, right = 5, bottom = 5, top = 5, },
                    alignment = { vertical = "top", horizontal = "left" },
                    size = 11,
                    color = { r = 0, g = 0, b = 0, a = 0 },
                    border = {
                        color = { r = 0, g = 0, b = 0, a = 1 },
                        thickness = 1,
                    },
                }
                setmetatable(obj, { __index = self })
                return obj
            end,
            mouse = function(self, keyEvent)
                local x, y = GetCursorPosition()
                if x > self.position.x and x < self.position.x + self.curWidth and y > self.position.y and y < self.position.y + self.curHeight then
                    if keyEvent == MOUSE_LDOWN then
                        self:onClick()
                    elseif keyEvent == MOUSE_LUP then
                        self:onRelease()
                    end
                    self:onHover()
                end
            end,
            close = function(self)
                self = nil
            end,
            draw = function(self)
            end,
            onHover = function(self)
            end,
            onClick = function(self)
            end,
            onRelease = function(self)
            end,
            closeUpper = function(self)
               self.win:close()
            end
        },
        new = function(self, name)
            local obj = {
                name = name,
                win = self,
                header = {
                    padding = { left = 5, right = 5, bottom = 5, top = 5, },
                    alignment = { vertical = "top", horizontal = "left" },
                    size = 11,
                    color = { r = 0, g = 0, b = 0, a = 0 },
                    border = {
                        color = { r = 0, g = 0, b = 0, a = 1 },
                        thickness = 1,
                    },
                    text = nil,
                },
                content = {
                    padding = { left = 5, right = 5, bottom = 5, top = 5, },
                    alignment = { vertical = "top", horizontal = "left" },
                    size = 11,
                    color = { r = 0, g = 0, b = 0, a = 0 },
                    border = {
                        color = { r = 0, g = 0, b = 0, a = 1 },
                        thickness = 1,
                    },
                    text = nil, --var, table or string
                },
                position = { x = 0, y = 0, },
                maxHeight = nil,
                maxWidth = nil,
                curHeight = nil,
                curWidth = nil,
                minHeight = nil,
                minWidth = nil,
                background = {
                    color = { r = 0, g = 0, b = 0, a = 0 },
                    img = nil,
                },
                zIndex = 0,
                grabbed = nil,
                buttons = {},
                windows = {},
            }
            setmetatable(obj, { __index = self })
            return obj
        end,
        close = function(self)
            self = nil
        end,
        closeUpper = function(self)
            self.win:close()
        end,
        drag = function(self, position)
            if position.x > self.position.x and position.x < self.position.x + self.curWidth and
                    position.y > self.position.y and position.y < self.position.y + self.curHeight then
                self.grabbed = { x = position.x - self.position.x, y = position.y - self.position.y }
            end
        end,
        drop = function(self, position)
            self.grabbed = nil
        end,
        createWindow = function(self, name)
            local w = self:new(name)
            self.windows[name] = w
            return w
        end,
        createButton = function(self, name)
            self.buttons[name] = self.button:new(name)
        end,
        mouse = function(self, keyEvent)
            for k, v in pairs(self.windows) do
                v:mouse(keyEvent)
            end
            for k, v in pairs(self.buttons) do
                v:mouse(keyEvent)
            end
            if keyEvent == MOUSE_LDOWN then
                local x, y = GetCursorPosition()
                self:drag({ x = x, y = y })
            elseif keyEvent == MOUSE_LUP then
                self:drop()
            end
        end,
        draw = function(self)
        --where is the position of the window (grabbed?)
        --calculate size of window
        --where is the mouse? Hover action?
        --draw background
        --draw border
        --draw content and header -> scrollbar?
        --draw buttons
        end,
    },
    new = function(self)
        local content = {
            windows = {}
        }
        setmetatable(content, { __index = self })
        return content
    end,
    createWindow = function(self, name)
        local w = self.window:new(name)
        self.windows[name] = w
        return w
    end,
    createMsgBox = function(self, name)
        local w = self.window:new(name)
        w.position = { x = 0, y = 0 }
        w.maxWidth, w.minWidth, w.maxHeight, w.minHeight = 200, 200, 100, 100
        w.header.text = "MessageBox"
        w.content.text = "Your Message"
        local b = w:createButton("ok_1")
        b.position = { x = 100, y = 70 }
        b.alignment.horizontal = "center"
        b.text = "OK"
        b.onRelease = b.closeUpper
        return w
    end,
    draw = function(self)
        for z = -10, 10, 1 do
            for k, v in pairs(self.windows) do
                if v.zIndex == z then v:draw() end
            end
        end
    end,
    mouse = function(self, keyEvent)
        for k, v in pairs(self.windows) do
            v:mouse(keyEvent)
        end
    end,
    close = function(self, name)
        self.windows[name]:close()
    end,
}